#pragma once

#include <QObject>
#include <QString>
#include <QList>
#include <memory>
#include <functional>
#include "kernel/domain/map_types.h"
#include "kernel/interfaces/ILogger.h"

namespace application {
namespace lift {

/**
 * @brief 电梯状态枚举
 */
enum class LiftStatus {
    Idle = 0,       // 空闲
    Busy = 1,       // 忙碌
    Error = 2,      // 错误
    Offline = 3,    // 离线
    Unknown = 4     // 未知
};

/**
 * @brief 电梯阶段枚举
 */
enum class LiftStage {
    QueryStatus = 0,              // 查询状态
    QueryStatusResponse = 1,      // 查询状态响应
    Call = 2,                     // 呼叫电梯
    CallResponse = 3,             // 呼叫响应
    ArriveCallFloor = 4,          // 到达呼叫楼层
    ArriveCallFloorResponse = 5,  // 到达呼叫楼层响应
    InCloseDoor = 6,              // 进入后关门
    InCloseDoorResponse = 7,      // 进入后关门响应
    ArriveAimFloor = 8,           // 到达目标楼层
    ArriveAimFloorResponse = 9,   // 到达目标楼层响应
    OutCloseDoor = 10,            // 出去后关门
    OutCloseDoorResponse = 11,    // 出去后关门响应
    Done = 12                     // 完成
};

/**
 * @brief 楼层信息结构
 */
struct FloorInfo {
    int floor;                  // 楼层号
    QString askPoint;           // 请求点
    QString waitPoint;          // 等待点
    QString interPoint;         // 内部点（电梯内）
    QString askAreaId;          // 请求点区域
    QString waitAreaId;         // 等待点区域
};

/**
 * @brief 电梯请求信息
 */
struct LiftRequestInfo {
    int liftNum;                // 电梯编号
    FloorInfo startFloor;       // 起始楼层
    FloorInfo targetFloor;      // 目标楼层
    int agvId;                  // AGV ID
};

struct LiftSegment {
    int liftNum{0};
    FloorInfo startFloor;
    FloorInfo targetFloor;
};

/**
 * @brief 电梯类型
 */
enum class LiftType {
    HK,
    MKLM,
    JZ,
    Unknown
};

using LiftResponseCallback = std::function<void()>;

/**
 * @brief 电梯基类
 */
class BaseLift : public QObject {
    Q_OBJECT

public:
    explicit BaseLift(int liftNum, LiftType type, std::shared_ptr<kernel::ILogger> logger = nullptr, QObject* parent = nullptr);
    virtual ~BaseLift() = default;

    // 基本信息
    int getLiftNum() const { return m_liftNum; }
    LiftStatus getStatus() const { return m_status; }
    LiftStage getStage() const { return m_stage; }
    bool isLocked() const { return m_isLocked; }
    bool isAgvControlled() const { return m_isAgvControlled; }
    LiftType getType() const { return m_type; }

    // 楼层管理
    void addFloorInfo(const FloorInfo& floorInfo);
    FloorInfo getFloorInfo(int floor) const;
    QList<FloorInfo> getAllFloorInfos() const { return m_floorInfos; }

    // 锁定管理
    void lock() { m_isLocked = true; }
    void unlock() { m_isLocked = false; }

    // 控制
    void setAgvControlled(bool controlled) { m_isAgvControlled = controlled; }
    void setStatus(LiftStatus status);
    void setStage(LiftStage stage);
    const LiftRequestInfo& currentRequest() const { return m_currentRequest; }
    void setCurrentRequest(const LiftRequestInfo& request) { m_currentRequest = request; }
    bool updateFloorAreaInfo(int floor, const QString& askAreaId, const QString& waitAreaId);

    // 虚函数：需要子类实现
    virtual bool initialize() = 0;
    virtual bool request(const LiftRequestInfo& request) = 0;
    virtual bool release() = 0;
    virtual void requestLiftStatus(const QString& uuid, LiftResponseCallback callback) = 0;
    virtual void requestLiftCall(int liftNum, int callFloor, int aimFloor, LiftResponseCallback callback) = 0;
    virtual void requestLiftInLiftCloseDoor(int liftNum, LiftResponseCallback callback) = 0;
    virtual void requestLiftOutLiftCloseDoor(int liftNum, LiftResponseCallback callback) = 0;
    virtual void requestDoorOpen(const QString& uuid, LiftResponseCallback callback) = 0;
    virtual void requestDoorClose(const QString& uuid, LiftResponseCallback callback) = 0;

signals:
    void statusChanged(LiftStatus status);
    void stageChanged(LiftStage stage);
    void liftArrived(int floor);
    void liftError(const QString& error);

protected:
    int m_liftNum;
    LiftStatus m_status = LiftStatus::Idle;
    LiftStage m_stage = LiftStage::QueryStatus;
    bool m_isLocked = false;
    bool m_isAgvControlled = false;
    QList<FloorInfo> m_floorInfos;
    std::shared_ptr<kernel::ILogger> m_logger;
    LiftRequestInfo m_currentRequest;
    LiftType m_type{LiftType::Unknown};
};

} // namespace lift
} // namespace application
